/*
//
//              INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license  agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in  accordance  with the terms of that agreement.
//    Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
//
//
*/

#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER) || \
    defined(UMC_ENABLE_AVS_VIDEO_ENCODER)

#include "umc_avs_processing_unit_sleep.h"
#include "vm_time.h"

namespace UMC
{

//
// this class was designed to keep consistency with other performers.
// actually, it does nothing, just sleep for little amount of time.
//

enum
{
    TIME_TO_SLEEP               = 1
};

AVSSleepProcessingUnit::AVSSleepProcessingUnit(void)
{

} // AVSSleepProcessingUnit::AVSSleepProcessingUnit(void)

AVSSleepProcessingUnit::~AVSSleepProcessingUnit(void)
{

} // AVSSleepProcessingUnit::~AVSSleepProcessingUnit(void)

#define AVS_PRINT_JOB(type, is_free) \
    if (pSlice->m_##type##Ctx.MbIndex < pSlice->m_##type##Ctx.MbLast) \
    { \
        sprintf(pcCur, "%s from % 6d to % 6d (%s)\n", \
                #type, \
                pSlice->m_##type##Ctx.MbIndex, \
                pSlice->m_##type##Ctx.MbLast, \
                (is_free) ? ("true") : ("false")); \
        pcCur += strlen(pcCur); \
    }

bool AVSSleepProcessingUnit::LoadJob(AVSListElement<AVSFrame> *pFrameList)
{
    // touch unreferenced parameter
    pFrameList = pFrameList;

#if 0
    // print frame statistic
    if (pFrameList)
    {
        char cStr[16 * 1024] = {0};
        char *pcCur = cStr;
        static char frameType[3][2] = {"I", "P", "B"};

        sprintf(pcCur, "================== NEW SLEEP ==================\n");
        pcCur += strlen(pcCur);
        sprintf(pcCur, "thread %d\n\n", m_threadNumber);
        pcCur += strlen(pcCur);

        while (pFrameList)
        {
            sprintf(pcCur, "%s frame number % 4d : %s%s\n",
                    frameType[pFrameList->m_picHeader.PictureType],
                    pFrameList->m_picHeader.picture_distance,
                    (pFrameList->m_picHeader.picture_structure) ? ("frame") : ("field pair"),
                    (pFrameList->IsShown()) ? ("") : (", not shown"));
            pcCur += strlen(pcCur);

            if (pFrameList->m_picHeader.picture_structure)
            {
                AVSListElement<AVSSlice> *pSlice;

                pSlice = pFrameList->m_Slices.GetHead();

                while (pSlice)
                {
                    if ((false == pSlice->m_bError) &&
                        (pSlice->m_bRecVacant) &&
                        (pSlice->m_recCtx.MbIndex < pSlice->m_recCtx.MbLast))
                    {
                        const Ipp16s *pCoeffsBuffer = pSlice->GetUsed();
                        AVS_DEC_ADDITIONAL_INFO *pExtraInfo = (AVS_DEC_ADDITIONAL_INFO *) pCoeffsBuffer;


                        if (pExtraInfo)
                        {
                        sprintf(pcCur, "reconstruction level is % 6d,\n",
                                pExtraInfo->m_maxVertOffset);
                        pcCur += strlen(pcCur);
                        }
                    }

                    AVS_PRINT_JOB(dec, pSlice->m_bDecVacant)
                    AVS_PRINT_JOB(rec, pSlice->m_bRecVacant)
                    AVS_PRINT_JOB(deb, pSlice->m_bDebVacant)

                    pSlice = pSlice->GetNext();
                }
            }
            else
            {
                eAVSPicStructure picStructure = AVS_UPPER_FIELD;
                int i;

                for (i = 0; i < 2; i += 1)
                {
                    AVSListElement<AVSSlice> *pSlice;

                    sprintf(pcCur, "field %d\n", i);
                    pcCur += strlen(pcCur);

                    pSlice = pFrameList->GetPicture(picStructure)->m_Slices.GetHead();

                    while (pSlice)
                    {
                        AVS_PRINT_JOB(dec, pSlice->m_bDecVacant)
                        AVS_PRINT_JOB(rec, pSlice->m_bRecVacant)
                        AVS_PRINT_JOB(deb, pSlice->m_bDebVacant)

                        pSlice = pSlice->GetNext();
                    }

                    picStructure = AVS_LOWER_FIELD;
                }
            }

            sprintf(pcCur, "\n");
            pcCur += strlen(pcCur);

            pFrameList = pFrameList->GetNext();
        }

        {
            DWORD nWritten;
            HANDLE hFile = CreateFile("e:\\avs_log.txt", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
            SetFilePointer(hFile, 0, 0, FILE_END);
            WriteFile(hFile, cStr, strlen(cStr), &nWritten, 0);
            CloseHandle(hFile);
        }
    }
#endif

    // this class should be the last one in a chain of performers,
    // so the method always returns true.
    return true;

} // bool AVSSleepProcessingUnit::LoadJob(AVSListElement<AVSFrame> *pFrameList)

Status AVSSleepProcessingUnit::DoJob(void)
{
    // just sleep for a while
    vm_time_sleep(TIME_TO_SLEEP);

    return UMC_ERR_NOT_ENOUGH_DATA;

} // Status AVSSleepProcessingUnit::DoJob(void)

void AVSSleepProcessingUnit::UnloadJob(void)
{
    // actually, it was just a halt of a thread for a while.
    // there is nothing to unload.

} // void AVSSleepProcessingUnit::UnloadJob(void)

} // namespace UMC

#endif // defined(UMC_ENABLE_AVS_VIDEO_DECODER)
